Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change exp_param to exp_params #3

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

bird-dancer
Copy link

this is to address the changes proposed in this pr: iotexproject/w3bstream#602

@hunshenshi
Copy link
Contributor

hunshenshi commented Aug 2, 2024

can I review the zokrates vm? It might help me better understand this PR.
Thanks

@bird-dancer
Copy link
Author

bird-dancer commented Aug 2, 2024

yes of course: https://github.com/ioCarb/zokrates-sprout (the proof format is not 100% correct yet, but its a small fix)
the expParams field would be used for the proving key, verifier key and the proving scheme, so it would look like this: expParams: [ "g16", "compressed proving.key", "compressed verify,key" ]

Here is an example workflow for the zokrates-cli https://zokrates.github.io/gettingstarted.html (because g16 is the default proving scheme its not explicitly set here but generally zokrates needs this information.)

We are in a Matrix chatroom with Wangweixiaohao, Xinxin and Simone and are still deciding where to host the zokrates "vm", thats why I haven't tried merging it yet.

@hunshenshi
Copy link
Contributor

hunshenshi commented Aug 5, 2024

codeExpParam is currently used in the risc0 VM. And its value is a JSON string, like "codeExpParam": "{\"image_id\":\"RANGE_ID\", \"elf\":\"RANGE_ELF\"}", code is here.
So I think it would be "codeExpParam": "{\"method\":\"g16\", \"proving_key\":\"compressed proving.key\"}".

Let me know what you think.

@bird-dancer
Copy link
Author

bird-dancer commented Aug 5, 2024

I have also initially considered this but this way one would either have to manually compress and copy the proving key or the ioctl would need a zokrates specific option. And for the sake of the ioctl user experience and the dev experience of someone implementing other zkp methods, I found expanding the exp params the best solution. Maybe there is a way I'm not thinking of?
Also since these keys will often be several GB in size there are likely performance penalties that come with the deserialization of the json (tho I have not tested this)

@hunshenshi
Copy link
Contributor

Also since these keys will often be several GB in size there are likely performance penalties that come with the deserialization of the json (tho I have not tested this)

If these keys are often several GB in size, there could be additional performance penalties on the network interface.
Maybe we should upload the proving_key to s3 or other object store, then download it at the vm server. And the codeExpParam will be "{\"method\":\"g16\", \"proving_key\":\"compressed proving.key url\"}"

@bird-dancer
Copy link
Author

That would be possible, however this still means that either the user would have to manually compress and upload the key for every circuit, which I would consider a hassle or there would need to be a specific option for zokrates in the ioctl.

Also the compiled circuit can be a few GB in size as well and in the case of a g16 scheme, the setup is even larger than the proving key.
For this example the out (which belongs in content), is 4.7G and the proving.key is 2.2G. The r1cs representation which (I think) could be theoretically translated to the normal Zokrates format is 1.3G.

@bird-dancer
Copy link
Author

bird-dancer commented Aug 6, 2024

Another theoretical option would be to perform the setup and possibly even compilation on the "vm" server which would result in only the .zok code which is a few kb being sent.
However the compilation and setup can take depending on the setup type (universal or g16) and circuit size between a few seconds and in extreme cases (large universal setup) 2h and takes up a lot of memory (40G).
In the case of G16 this is a lot quicker and lighter on memory, but it uses a local source of entropy which can be used to fake proofs unless it is part of a multi party setup (like powers of tau) more here.
Performing a mpc would require extensive changes to the zokrates "vm" code, require the initializer of the setup to have access to the compiled circuit and the verifier solidity contract can only be generated with the outputs of the setup. So a back and forth between the user and prover or communication between provers would probably be necessary.

@hunshenshi
Copy link
Contributor

I perpared a script in w3bstream that can compress code, upload it to IPFS, and return a URL. (The VM developer can customize the compression algorithm and storage medium; they just need to download and decompress it on the VM server.)
Then we can change the codeExpParam or code field (if the size of code is bigger) of project file to a URL, and parse it in the VM server.
like this

{
  "defaultVersion": "0.1",
  "versions": [
    {
      ...
      "codeExpParam": "{\"method\":\"g16\", \"proving_key\":\"compressed proving.key url\"}",
      "code": "789cecbd3baf6c3db32e94f32b5674..."
    }
  ]
}

if the size of code is bigger, the project file like this

{
  "defaultVersion": "0.1",
  "versions": [
    {
      ...
      "codeExpParam": "{\"method\":\"g16\", \"proving_key\":\"compressed proving.key url\"}",
      "code": "ipfs://ipfs.xxx.iotex.io/QmY5Y2HD9WXYhhPg3CJbh2DS7mXwS2dUiyk3gRutLYQE6u"
    }
  ]
}

@bird-dancer
Copy link
Author

Ok that would work.
Do you think the vm should scan if the strings start with "ipfs" or should this be an enum or maybe a flag indicating whether the field is an address or contains the actual value?
Because if we wouldnt check for ipfs we could change the encoding to base64, which would reduce the param size by about 30-40%.

@bird-dancer
Copy link
Author

Also the compiled circuit can be a few GB in size as well and in the case of a g16 scheme, the setup is even larger than the proving key. For this example the out (which belongs in content), is 4.7G and the proving.key is 2.2G. The r1cs representation which (I think) could be theoretically translated to the normal Zokrates format is 1.3G.

And I think this message was a little misleading, I was referring to the uncompressed size. The compressed the sizes are:

  • 204M for out (414M hex encoded, 276M base64 encoded) (uncompressed 4.7G).
  • 1.9G for proving.key (3.7G base16, and 2.5G base64) (uncompressed 2.2G)

It seems the compression rate for the circuits are a lot better

@hunshenshi
Copy link
Contributor

hunshenshi commented Aug 15, 2024

Ok that would work. Do you think the vm should scan if the strings start with "ipfs" or should this be an enum or maybe a flag indicating whether the field is an address or contains the actual value? Because if we wouldnt check for ipfs we could change the encoding to base64, which would reduce the param size by about 30-40%.

I think the VM doesn't need to scan; it can be specified in the documentation to only accept either a URL or the actual value.
Moreover, w3bstream already supports VM type registration. If some developers don't want to use a URL or actual value, they can register their own VM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants